#include <iostream>
#include <string>
#include <uv.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

#include "config.h"
#include "core.h"
#include "log.h"

const std::string SERVICE_NAME = "eagle";
std::string g_ConfigFilename;

void PrintVersionInfo()
{
    std::cout << SERVICE_NAME << " v" << EAGLE_VERSION << " Build in " << __DATE__ << " " << __TIME__ << std::endl;
}

bool ParseProgmaOptions(int nArgc, char **szArgs)
{
    for (int i = 1; i < nArgc; ++i)
    {
        if (szArgs[i] == std::string("-h") || szArgs[i] == std::string("--help"))
        {
            std::cout << "Usage:\n"
                         "    --help,-h                 Print help message\n"
                         "    --version,-v              Print version info\n"
                         "    --config,-c [string]      config file\n"
                      << std::endl;
            exit(0);
        }
    }
    for (int i = 1; i < nArgc; ++i)
    {
        if (szArgs[i] == std::string("-v") || szArgs[i] == std::string("--version"))
        {
            PrintVersionInfo();
            exit(0);
        }
    }
    for (int i = 1; i < nArgc - 1; ++i)
    {
        if (szArgs[i] == std::string("-c") || szArgs[i] == std::string("--config"))
        {
            g_ConfigFilename = szArgs[i + 1];
        }
    }
    return true;
}

void application_signal_stop(int nSignal)
{
    Core::GetInstance().Stop();
}

int main(int nArgc, char **szArgs)
{
    signal(SIGQUIT, application_signal_stop);
    signal(SIGTERM, application_signal_stop);

    ParseProgmaOptions(nArgc, szArgs);

    Config &config = Config::GetInstance();

    if (!config.loadConfig(g_ConfigFilename))
    {
        LOG_ERROR("config file[%s] load failed", g_ConfigFilename.c_str());
        return 1;
    }

    Core &core = Core::GetInstance();

    if (!Core::GetInstance().Init(config))
    {
        LOG_ERROR("core Init failed");
        return -1;
    }
    if (!Core::GetInstance().Start())
    {
        LOG_ERROR("core Start failed");
        return -1;
    }
    Core::GetInstance().Run();
    return 0;
}